from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import TimeoutException
from app.config import config
import requests
import datetime
import json
import redis
import time
import sys



r = redis.Redis('localhost', port=6379, db=1, decode_responses=True)


options = webdriver.ChromeOptions()
# if r.get('jd') is not None:
#     options.add_argument('--headless')
browser = webdriver.Chrome(options=options)
wait = WebDriverWait(browser, 10)


# 消费
class Consumer(object):
    # 初始化参数
    def __init__(self, *args, **kwargs):
        for key, val in kwargs.items():
            setattr(self, key, val)
        self.browser = browser
        self.wait = wait
        print('任务时间: {}'.format(self.task_at))

    # 当前时间
    def current_datetime(self):
        return '[{}]'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

    # 登陆
    def login(self):
        self.browser.get('https://passport.jd.com/new/login.aspx')
        print('{} 用户登陆...'.format(self.current_datetime()))
        if r.get('jd') is None:
            while True:
                try:
                    self.wait.until(
                        EC.text_to_be_present_in_element((
                            By.CSS_SELECTOR,
                            '#shortcut > div > ul.fr > li.shortcut_btn.fore2 > div > a'
                        ), '我的订单'))
                    r.set('jd', json.dumps(self.browser.get_cookies()))
                    break
                except TimeoutException:
                    print('继续等待扫码获取')
        else:
            print('{} 查到有cookies, 使用此身份登陆.'.format(self.current_datetime()))

        listCookies = json.loads(r.get('jd'))
        self.browser.delete_all_cookies()

        for cookie in listCookies:
            self.browser.add_cookie(cookie)
        print('{} 登陆成功'.format(self.current_datetime()))

    # 指定时间执行
    def timing(self):
        start_time = datetime.datetime.strptime(self.task_at, '%Y-%m-%d %H:%M:%S')
        while datetime.datetime.now() < start_time:
            sys.stdout.write('当前时间: {}\r'.format(self.current_datetime()))
            time.sleep(1)

    # 进入支付收银台
    def entry_pay(self):
        print('{} 进入支付收银台'.format(self.current_datetime()))
        self.browser.get(self.order_url)
        print('{} 进入支付页面'.format(self.current_datetime()))
        assert '收银台' in self.browser.title, '没有成功进入收银台'

    # 是否验证条件，等待出现指定价格, 出现后跳出循环
    def checkout_select(self):
        num = 0
        while True:
            try:
                self.wait.until(
                    EC.presence_of_element_located((
                        By.CSS_SELECTOR,
                        '#payChannelListId > div:nth-child(5) > div > div:nth-child(6) > a'
                    )))

                price = self.browser.find_element_by_xpath(
                    '//b[contains(text(),"300")]')
                if price:
                    print('找到了300块,支付中')
                    break
            except NoSuchElementException:
                self.browser.refresh()
                num += 1
                print('没有找到,尝试刷新页面, 次数:{}'.format(num))

    # 收银台支付
    def checkstand(self, is_checkout=False):
        self.browser.execute_script('''
        var pay_no = 2
        var a_no = 0
        var param = {
            "reqType": 0,
            "shouldPay": globalVar.shouldPay,
            "pwdLevel": "2",
            "password": "123457",
            "orderId": globalVar.orderId,
            "paySign": globalVar.paySign,
            "nextStepInfoSign": "",
            "payingChannelList": [{
                "payAmount": avalon.vmodels['vmNewUser'].payAmount,
                "channelId": avalon.vmodels['vmNewUser'].data.payChannelList[pay_no].channelId,
                "channelName": avalon.vmodels['vmNewUser'].data.payChannelList[pay_no].channelName,
                "channelType": avalon.vmodels['vmNewUser'].data.payChannelList[pay_no].channelType,
                "pwdLevel": avalon.vmodels['vmNewUser'].data.payChannelList[pay_no].pwdLevel,
                "channelSign": avalon.vmodels['vmNewUser'].data.payChannelList[pay_no].channelSign,
                "payCoupon": {
                    "canUse": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].canUse,
                    "isDefault": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].isDefault,
                    "appId": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].appId,
                    "isRandomCutOff": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].isRandomCutOff,
                    "discountAmount": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].discountAmount,
                    "prizeName": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].prizeName,
                    "prizeId": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].prizeId,
                    "promotionCustomerId": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].promotionCustomerId,
                    "promotionAccount": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].promotionAccount,
                    "entranceId": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].entranceId,
                    "prizeTypeCode": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].prizeTypeCode,
                    "cutOffType": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].cutOffType,
                    "promotionDesc": avalon.vmodels["vmNewUser"].data.payChannelList[pay_no].cutOffCouponList[a_no].promotionDesc
                },
                "cardPayReqVo": {
                    "cardId": avalon.vmodels['vmNewUser'].data.payChannelList[pay_no].bindingCardInfo.cardId,
                    "cardType": avalon.vmodels['vmNewUser'].data.payChannelList[pay_no].bindingCardInfo.cardType,
                    "bankCode": avalon.vmodels['vmNewUser'].data.payChannelList[pay_no].bindingCardInfo.bankCode,
                    "cvv2": avalon.vmodels['vmNewUser'].data.payChannelList[pay_no].bindingCardInfo.cvv2
                }
            }],
            "riskReqVo": {
                "deviceId": getCookie("3AB9D23F7A4B3C9B"),
                "fingerprint": globalVar.riskInfo.fingerprint,
                "jsContent": globalVar.riskInfo.jsContent
            },
            "successURL": globalVar.successURL,
            "pageId": globalVar.pageId,
            "forcebot": "",
            "reqTime": (new Date).getTime(),
            "aksEncStr": encryptUtils.aksEncrypt(JSON.stringify({"password":"123456"}))
        }
        $.ajax({
            type: "post",
            contentType: "application/json",
            dataType: "json",
            timeout: "15000",
            data: JSON.stringify(param),
            url: "/payment/combinePay?cashierId=" + globalVar.cashierId,
            success: function(a) {
                try {
                    channelPay.callback(a)
                } catch (e) {
                    commonUtils.logErrorInfo("cashier.common.js  channelPay.ansyPay", e.stack)
                }
            },
            error: function() {
                this.timeoutCount < 2 ? (this.timeoutCount++, channelPay.ansyPay()) : (channelPay._this.payLoading = !1, channelPay._this.errorInfo = "\u7f51\u7edc\u5f00\u5c0f\u5dee\u5566\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5\u5427~")
            }
        })
        ''')
        print('{} 支付完成'.format(self.current_datetime()))


    # 主操作
    def run(self):
        # 登陆
        self.login()
        # 进入收银台
        self.entry_pay()
        # 指定时间执行
        self.timing()

        # 支付提交
        self.checkstand()


for item in config:
    jd = Consumer(**item).run()
